using System;
using System.Collections.Generic;
using Sedge.Core.App;
using Sedge.Core.Configuration;
using Sedge.Core.Globalization;
using Sedge.Core.Utils;

namespace Sedge.Core.Execution
{
	public class ScheduleRunner
	{
		private readonly List<IStepController> _stepControllers = new List<IStepController>();
	    private readonly Suite _suite;

		public ScheduleRunner(Suite suite)
		{
		    _suite = suite;
		}

	    public void Run(bool silent)
		{
			PrepareSchedule();

			foreach (Step step in _suite.Steps)
			{
				IStepController controller = CreateStepController(step);
				controller.Initialize(_suite, step.Options);
				_stepControllers.Add(controller);
			}
			
			IMasterController masterController = CreateMasterController();
			masterController.Show(_suite, _stepControllers);
		}

		private void PrepareSchedule()
		{
			_suite.WorkingFolder = GetReportFolder();
			_suite.ImagesFolder = GetSubFolder(_suite.WorkingFolder, Branding.ReportImages);
			_suite.FilesFolder = GetSubFolder(_suite.WorkingFolder, Branding.ReportFiles);
			_suite.UserFilesFolder = GetSubFolder(_suite.WorkingFolder, Branding.ReportUserFiles);
			_suite.HtmlFilesFolder = GetSubFolder(_suite.WorkingFolder, Branding.ReportHtmlFiles);
		}

		protected T CreateUIController<T>(string assemblyName, string className) where T: class 
		{
			if (String.IsNullOrEmpty(assemblyName))
			{
				assemblyName = _suite.UISource;
			}

			assemblyName = ReturnFullPath(assemblyName);
			T result = TypeActivator.Activate<T>(assemblyName, className);
			
			if (result == null)
			{
				ErrorHandler.Error(Locale.Strings.ETypeNotFound, className);
			}

			return result;
		}

		private IStepController CreateStepController(Step step)
		{
			return CreateUIController<IStepController>(step.Assembly, String.Concat(step.Name, "Controller"));
		}

		private IMasterController CreateMasterController()
		{
			return CreateUIController<IMasterController>(String.Empty, "MasterController");
		}

        private static string ReturnFullPath(string testPath)
        {
            if (String.IsNullOrEmpty(testPath))
                testPath = ".";

            string path = Services.FileSystem.Path.GetFullPath(testPath);

            return path;
        }

        private static string GetReportFolder()
        {
            string pattern = String.Format("{0}\\Report{1}{2}{3}", Branding.AppName, DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
            string tmpPath = Services.FileSystem.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), pattern);
            string path = tmpPath + "_01";

            int i = 1;
            while (Services.FileSystem.Directory.Exists(path))
            {
                path = String.Format("{0}_{1:D2}", tmpPath, i);
                i++;
            }
            Services.FileSystem.Directory.CreateDirectory(path);

            return path;
        }

        private static string GetSubFolder(string folder, string subfolder)
        {
            string path = Services.FileSystem.Path.Combine(folder, subfolder);
            if (!Services.FileSystem.Directory.Exists(path))
            {
                Services.FileSystem.Directory.CreateDirectory(path);
            }

            return path;
        }

	}
}